# -*- coding: utf-8 -*-
import sys
from PyQt5 import QtCore, QtGui
from PyQt5.QtWidgets import QWidget, QApplication,QMainWindow
from Public.RequestUtils import StocksRequest
# 绘制行情类
class 分时画图工具类(QWidget):
    # 设置grid的上下左右补丁边距
    左侧补丁边距 = 45
    右侧补丁边距 = 245
    顶部补丁边距 = 25
    底部补丁边距 = 17
    总宽 = 左侧补丁边距 + 右侧补丁边距
    总高 = 顶部补丁边距 + 底部补丁边距
    主窗宽 = 0
    表格高度 = 0
    表格宽度 = 0

    def __init__(self, parent):
        # 初始化
        super(分时画图工具类, self).__init__()
        self.parent = parent
        self.paint = QtGui.QPainter()
        # 度量尺对象
        self.metrics = self.paint.fontMetrics()
        # 设置字体库
        self.字体库 = dict()
        self.字体库['默认字体'] = QtGui.QFont('Serif', 9, QtGui.QFont.Light)
        self.字体库['雅黑加粗字体'] = QtGui.QFont('Serif', 12, QtGui.QFont.Bold)
        self.字体库['雅黑字体'] = QtGui.QFont('Serif', 12, QtGui.QFont.Light)
        self.设置当前字体('默认字体')
        # 设置笔刷样式库
        self.笔刷样式库 = dict()
        # 红色 1px粗  1px点 2px距 线条
        self.笔刷样式库['红色1px虚线'] = QtGui.QPen(QtCore.Qt.red, 1, QtCore.Qt.DashLine)
        self.笔刷样式库['红色1px虚线'].setDashPattern([1, 2])

        self.笔刷样式库['红色1px线'] = QtGui.QPen(QtCore.Qt.red, 1, QtCore.Qt.SolidLine)
        self.笔刷样式库['红色2px线'] = QtGui.QPen(QtCore.Qt.red, 2, QtCore.Qt.SolidLine)
        self.笔刷样式库['红色3px线'] = QtGui.QPen(QtCore.Qt.red, 3, QtCore.Qt.SolidLine)
        self.笔刷样式库['黄色1px线'] = QtGui.QPen(QtCore.Qt.yellow, 1, QtCore.Qt.SolidLine)
        self.笔刷样式库['白色1px线'] = QtGui.QPen(QtCore.Qt.white, 1, QtCore.Qt.SolidLine)
        self.笔刷样式库['灰色1px线'] = QtGui.QPen(QtCore.Qt.gray, 1, QtCore.Qt.SolidLine)
        self.笔刷样式库['绿色1px线'] = QtGui.QPen(QtCore.Qt.green, 1, QtCore.Qt.SolidLine)
        self.笔刷样式库['绿色2px线'] = QtGui.QPen(QtCore.Qt.green, 2, QtCore.Qt.SolidLine)

        self.笔刷样式库['亮蓝1px虚线'] = QtGui.QPen(QtCore.Qt.cyan, 1, QtCore.Qt.DashLine)
        self.笔刷样式库['亮蓝1px虚线'].setDashPattern([3, 2])


    def 开始绘制(self):
        self.绘制表格()
        self.绘制左右侧的价格刻度()
        self.绘制时间轴刻度()
        self.绘制表格上方的股票信息()
        self.绘制股价走势()
        self.绘制成交量走势表格()
        self.绘制成交量()
        self.绘制盘口()


    def paintEvent(self, event):
        # 获得窗口的长和宽
        主窗口大小 = self.parent.size()
        self.主窗宽 = 主窗口大小.width()
        self.主窗高 = 主窗口大小.height()
        self.表格高度 = self.主窗高 - self.顶部补丁边距
        self.表格宽度 = self.主窗宽 - self.总宽 - 2
        self.paint.begin(self)
        self.开始绘制()
        self.paint.end()  # 结束
    def 设置当前字体(self, code='默认字体'):
        self.paint.setFont(self.字体库[code])

    '''设置使用的笔刷'''

    def 设置当前笔刷(self, code='default'):
        self.paint.setPen(self.笔刷样式库[code])

    def 绘制表格(self):
        self.设置当前笔刷('红色1px线')
        self.paint.setBrush(QtCore.Qt.NoBrush)

        # 画分主边框
        self.paint.drawRect(0, 0,self.主窗宽 - 1,self.主窗高-1)
        self.paint.drawRect(self.左侧补丁边距, self.顶部补丁边距,self.主窗宽 - self.总宽, self.主窗高 )
        # 成交量和走势的分界线(成交量和走势三七割)
        self.paint.drawLine(self.左侧补丁边距, self.表格高度 * 0.7 + self.顶部补丁边距,self.主窗宽 - self.右侧补丁边距, self.表格高度 * 0.7 + self.顶部补丁边距)
        self.paint.drawLine(self.左侧补丁边距, self.表格高度  * 0.7 + self.顶部补丁边距+self.底部补丁边距, self.主窗宽 - self.右侧补丁边距,self.表格高度 * 0.7+ self.顶部补丁边距+self.底部补丁边距)

        # 股票昨收中间线走势
        self.paint.drawLine(self.左侧补丁边距 + 1, self.表格高度 * 0.35 + self.顶部补丁边距,self.主窗宽 - self.右侧补丁边距, self.表格高度 * 0.35 + self.顶部补丁边距)
        # 其他线条
        #self.paint.drawLine(0, self.主窗高 - self.底部补丁边距, self.主窗宽 - self.右侧补丁边距 + 44,self.主窗高 - self.底部补丁边距)
        #self.paint.drawLine(0, self.主窗高 - self.底部补丁边距 + 16, self.主窗宽, self.主窗高 - self.底部补丁边距 + 16)
        self.paint.drawLine(self.主窗宽 - self.右侧补丁边距 + 44, 0,self.主窗宽 - self.右侧补丁边距 + 44, self.主窗高 - self.底部补丁边距 + 16)


    def 绘制表格上方的股票信息(self):
        self.设置当前笔刷('黄色1px线')
        self.paint.drawText(4 + self.左侧补丁边距, self.顶部补丁边距 - 4, str(self.parent.股票数据['股票名称']))  # 股票名称
        self.paint.drawText(4 + self.左侧补丁边距 + 140, self.顶部补丁边距 - 4 , str('均价线：'))  # 均价线
        上一个交易日收盘价 = self.parent.股票数据['上一个交易日收盘价']
        今收 = self.parent.股票数据['当前价']
        均价 =  self.parent.股票数据['分时数据']['均价'][-1]

        if 上一个交易日收盘价 > 今收:
            self.设置当前笔刷('绿色1px线')
            str_1 = '%.2f -%.2f' % (今收, 上一个交易日收盘价 - 今收)
        if 上一个交易日收盘价 == 今收:
            self.设置当前笔刷('白色1px线')
            str_1 = '%.2f +%.2f' % (今收, 0.00)
        if 上一个交易日收盘价 < 今收:
            self.设置当前笔刷('红色1px虚线')
            str_1 = '%.2f +%.2f' % (今收, 今收 - 上一个交易日收盘价)



        self.paint.drawText(4 + self.左侧补丁边距 + 60, self.顶部补丁边距 - 4, str(str_1))
        self.paint.drawText(4 + self.左侧补丁边距 + 185, self.顶部补丁边距 - 4, str('%.2f' % 均价))  #

        # 涨停价
        self.设置当前笔刷('红色1px虚线')
        self.paint.drawText(4 + self.左侧补丁边距 + 230, self.顶部补丁边距 - 4,
                            str('涨停价:%.2f' % (self.parent.股票数据['涨停价'])))  # 均价
        # 跌停价
        self.设置当前笔刷('绿色1px线')
        self.paint.drawText(4 + self.左侧补丁边距 + 310, self.顶部补丁边距 - 4,
                            str('跌停价:%.2f' % (self.parent.股票数据['跌停价'])))  # 均价

    def 绘制成交量走势表格(self):

        当日最高成交量 = self.parent.股票数据['当前最高成交量']
        间隔偏移 = 当日最高成交量 / (self.表格高度 * 0.3)
        self.设置当前笔刷('红色1px线')
        grid_num = 6
        x = grid_num
        cnt = self.表格高度 * 0.3 / grid_num
        for i in range(1, grid_num):
            self.设置当前笔刷('红色1px虚线')
            # 计算坐标
            y1 = self.顶部补丁边距 + (self.表格高度 * 0.7) + i * cnt
            x1 = self.左侧补丁边距
            x2 = self.左侧补丁边距 + self.主窗宽 - self.总宽

            self.paint.drawLine(x1, y1, x2, y1)  # 画价位虚线

            vol_int = int(cnt * x * 间隔偏移)
            vol_str = str(vol_int)
            fw = self.metrics.width(vol_str)  # 获得文字宽度
            fh = self.metrics.height() / 2  # 获得文字高度
            self.设置当前笔刷('黄色1px线')
            self.paint.drawText(x2 + 40 - fw, y1 + fh, vol_str)  # 写入文字
            self.设置当前笔刷('白色1px线')
            self.paint.drawText(x1 - 2 - self.metrics.width(str(x)), y1 + fh, str(x))  # 写入文字
            x -= 1

    def 绘制左右侧的价格刻度(self):

        当前最高价 = self.parent.股票数据['高价']
        当前最低价 = self.parent.股票数据['低价']
        上一个交易日收盘价 = self.parent.股票数据['上一个交易日收盘价']

        top = 当前最高价 - 上一个交易日收盘价
        bottom = 上一个交易日收盘价 - 当前最低价
        if top > bottom:
            padding = top
        else:
            padding = bottom
        limit_top = 上一个交易日收盘价 + padding
        limit_low = 上一个交易日收盘价 - padding

        px_h_radio = (self.表格高度 * 0.7) / ((limit_top - limit_low) * 100)

        self.设置当前笔刷('红色1px虚线')

        grid_num = 16
        cnt = self.表格高度 * 0.7 / 16

        for i in range(0, grid_num):
            self.设置当前笔刷('红色1px虚线')
            # 计算坐标
            y1 = self.顶部补丁边距 + i * cnt
            x1 = self.左侧补丁边距
            x2 = self.左侧补丁边距 + self.主窗宽 - self.总宽

            self.paint.drawLine(x1, y1, x2, y1)  # 画价位虚线

            price_float = (limit_top - ((i * cnt) / px_h_radio / 100))  # 计算价格
            price = '%4.2f' % (price_float)  # 格式化价格成str

            fw = self.metrics.width(price)  # 获得文字宽度
            fh = self.metrics.height() / 2  # 获得文字高度

            radio_float = (price_float / 上一个交易日收盘价 - 1) * 100  # 计算波动百分比
            radio_str = "%2.2f%%" % (radio_float)  # 格式化百分比成str

            r_fw = self.metrics.width(radio_str)
            r_fh = self.metrics.height() / 2
            # 判断文字使用的颜色
            if price_float == 上一个交易日收盘价:
                self.设置当前笔刷('白色1px线')
            if price_float < 上一个交易日收盘价:
                self.设置当前笔刷('绿色1px线')
            if i == 0:
               self.paint.drawText(x1 - fw - 2, y1 + fh, price)  # 写入文字
               self.paint.drawText(x2 + 40 - r_fw, y1 + r_fh, radio_str)  # 写入文字
               self.设置当前笔刷('绿色1px线')
               price_float = (limit_top - ((16 * cnt) / px_h_radio / 100))  # 计算价格
               radio_float = (price_float / 上一个交易日收盘价 - 1) * 100
               radio_str = "%2.2f%%" % (radio_float)  # 格式化百分比成str
               r_fw = self.metrics.width(radio_str)
               self.paint.drawText(x1 - fw - 2, y1+16* cnt + fh, '%4.2f' %(price_float))  # 写入文字
               self.paint.drawText(x2 + 40 - r_fw, y1+16*cnt + r_fh,radio_str)  # 写入文字
            else:
                self.paint.drawText(x1 - fw - 2, y1 + fh, price)  # 写入文字
                self.paint.drawText(x2 + 40 - r_fw, y1 + r_fh, radio_str)  # 写入文字


    def 绘制时间轴刻度(self):

        文字的宽度 = self.metrics.width('00:00')  # 计算文字的宽度


        y1 = self.顶部补丁边距
        y2 = y1 + (self.表格高度 * 0.7 )

        # 时间轴中线
        self.设置当前笔刷('红色1px线')
        x_pos = self.表格宽度 / 2 + self.左侧补丁边距

        self.paint.drawLine(x_pos, y1, x_pos, y2)
        self.paint.drawText(x_pos - 文字的宽度 / 2, y2 + 12, str('13:00'))

        # 时间轴09点30分
        x_pos = self.左侧补丁边距
        self.paint.drawText(x_pos, y2 + 12, str('09:30'))

        # 时间轴10点30分
        x_pos = self.表格宽度 * 0.25 + self.左侧补丁边距
        self.paint.drawLine(x_pos, y1, x_pos, y2)
        self.paint.drawText(x_pos - 文字的宽度 / 2, y2 + 12, str('10:30'))

        # 时间轴14点00分
        x_pos = self.表格宽度 * 0.75 + self.左侧补丁边距
        self.paint.drawLine(x_pos, y1, x_pos, y2)
        self.paint.drawText(x_pos - 文字的宽度 / 2, y2 + 12, str('14:00'))

        # 时间轴15点00分
        x_pos = self.表格宽度 + self.左侧补丁边距
        self.paint.drawText(x_pos - 文字的宽度, y2 + 12, str('15:00'))

        # 时间虚线 by 30min
        self.设置当前笔刷('红色1px虚线')
        x_pos_array = [0.125, 0.375, 0.625, 0.875]
        for i in x_pos_array:
            x_pos = self.表格宽度 * i + self.左侧补丁边距
            self.paint.drawLine(x_pos, y1, x_pos, y2)


    def 绘制股价走势(self):


        当前最高价 = self.parent.股票数据['高价']
        当前最低价 = self.parent.股票数据['低价']
        上一个交易日收盘价 = self.parent.股票数据['上一个交易日收盘价']

        top = 当前最高价 - 上一个交易日收盘价
        bottom = 上一个交易日收盘价 - 当前最低价
        if top > bottom:
            padding = top
        else:
            padding = bottom

        limit_top = 上一个交易日收盘价 + padding
        limit_low = 上一个交易日收盘价 - padding

        h_radio = (self.表格高度 * 0.7) / ((limit_top - limit_low) * 100)

        w_radio = (self.主窗宽 - self.总宽 - 2) / 242.00
        w = self.左侧补丁边距

        self.设置当前笔刷('白色1px线')
        path = QtGui.QPainterPath()
        path.moveTo(w, (limit_top - self.parent.股票数据['开盘价']) * 100 * h_radio + self.顶部补丁边距)
        i = 1

        for price in self.parent.股票数据['分时数据']['价格']:
            w = i * w_radio + self.左侧补丁边距
            y = (limit_top - price) * 100 * h_radio + self.顶部补丁边距
            path.lineTo(w, y)
            i += 1
        self.paint.drawPath(path)

        self.设置当前笔刷('黄色1px线')
        path = QtGui.QPainterPath()
        w = self.左侧补丁边距
        path.moveTo(w, (limit_top - self.parent.股票数据['开盘价']) * 100 * h_radio + self.底部补丁边距)
        i = 1
        for price in self.parent.股票数据['分时数据']['均价']:
            w = i * w_radio + self.左侧补丁边距
            y = (limit_top - price) * 100 * h_radio + self.底部补丁边距
            path.lineTo(w, y)
            i += 1
        self.paint.drawPath(path)

    def 绘制成交量(self):
        当前最高成交量 = self.parent.股票数据['当前最高成交量']  # 最大分钟成交量

        w_radio = (self.主窗宽 - self.总宽 - 2) / 242.00
        h_radio = ((self.主窗高 - self.总高 - 2) * 0.3 -  self.顶部补丁边距) / 当前最高成交量

        y = (self.主窗高 -  self.总高) + self.顶部补丁边距+ self.底部补丁边距-1

        self.设置当前笔刷('黄色1px线')

        for i in range(1, len(self.parent.股票数据['分时数据']['成交量']) + 1):
            x = i * w_radio + self.左侧补丁边距
            y2 = h_radio * self.parent.股票数据['分时数据']['成交量'][i - 1]
            self.paint.drawLine(x, y - 1, x, y - y2)

    def 绘制盘口(self):
        盘口X坐标位 = self.主窗宽 - self.右侧补丁边距 + 44
        self.设置当前笔刷('红色1px线')

        self.paint.drawLine(盘口X坐标位, 23, self.主窗宽, 23)
        self.paint.drawLine(盘口X坐标位, 45, self.主窗宽, 45)

        self.paint.drawLine(盘口X坐标位, 227, self.主窗宽, 227)
        self.paint.drawLine(盘口X坐标位, 250, self.主窗宽, 250)
        self.paint.drawLine(盘口X坐标位, 431, self.主窗宽, 431)
        self.paint.drawLine(盘口X坐标位, 552, self.主窗宽, 552)
        self.paint.drawLine(盘口X坐标位, 575, self.主窗宽, 575)
         # 股票名称和代码
        self.设置当前字体('雅黑加粗字体')
        self.设置当前笔刷('黄色1px线')
        股票名称 = str('%s %s' % (self.parent.股票数据['股票代码'], self.parent.股票数据['股票名称']))
        self.paint.drawText(盘口X坐标位 + 35, 18, 股票名称)
        # 委比和委差
        self.设置当前字体('雅黑字体')
        self.paint.drawText(盘口X坐标位 + 3, 245, str('最新'))
        self.paint.drawText(盘口X坐标位 + 100, 245, str('现手'))
        self.设置当前笔刷('绿色1px线')

        self.paint.drawText(盘口X坐标位 + 3, 39, str('委比'))
        self.paint.drawText(盘口X坐标位 + 100, 39,  str('委差'))

        上一个交易日收盘价 = self.parent.股票数据['上一个交易日收盘价']
        今收 = self.parent.股票数据['当前价']
        if 上一个交易日收盘价 > 今收:
            self.设置当前笔刷('绿色1px线')
        if 上一个交易日收盘价 == 今收:
            self.设置当前笔刷('白色1px线')
        if 上一个交易日收盘价 < 今收:
            self.设置当前笔刷('红色1px虚线')

        left_field_list = ['涨跌', '振幅', '总量', '总额', '高价', '低价']

        i = 1
        for field in left_field_list:
            field_str = str(field)
            r_fw = self.metrics.width(field_str)
            if '总量' == field_str:
                _value  = '%.2f万' % (self.parent.股票数据['总量']/10000)
            elif '总额' == field_str:
               _value = '%.2f万' % (self.parent.股票数据['总额']/10000)
            else:
                _value = (self.parent.股票数据[field_str])

            self.paint.drawText(盘口X坐标位 + 3, 430 + (i * 19), field_str)
            self.paint.drawText(盘口X坐标位 + r_fw + 15, 430 + (i * 19), str(_value))
            i += 1



        right_field_list = ['均价', '昨收', '今开', '最高', '量比', '均量']

        i = 1

        for field in right_field_list:
            field_str = str(field)
            self.paint.drawText(盘口X坐标位 + 120, 430 + (i * 19), field_str)
            i += 1

        self.paint.drawText(盘口X坐标位 + 3, 570, str('外盘'))
        self.paint.drawText(盘口X坐标位 + 100, 570,  str('内盘'))



        i = 0
        sell_queue = ['卖⑩', '卖⑨', '卖⑧', '卖⑦', '卖⑥', '卖⑤', '卖④', '卖③', '卖②', '卖①']
        r_fw = self.metrics.width('卖⑩')
        for sell in sell_queue:
            sell_str = str(sell)
            价格 = '{:.2f}'.format(self.parent.股票数据['盘口数据']['ask{index}'.format(index=10 - i)])
            手数 = str(self.parent.股票数据['盘口数据']['ask{index}_volume'.format(index=10 - i)])
            self.paint.drawText(盘口X坐标位  + 3, 62 + (i * 18), sell_str)
            self.paint.drawText(盘口X坐标位 + r_fw+20, 62 + (i * 18), 价格)
            self.paint.drawText(盘口X坐标位 + r_fw + 110, 62 + (i * 18), 手数)
            i += 1
        # 买①②③④⑤
        buy_queue = ['买①', '买②', '买③', '买④', '买⑤', '买⑥', '买⑦', '买⑧', '买⑨', '买⑫']
        for buy in buy_queue:
            buy_str = str(buy)
            价格 = str(self.parent.股票数据['盘口数据']['bid{index}'.format(index=(i+1)-10)])
            手数 = str(self.parent.股票数据['盘口数据']['bid{index}_volume'.format(index=(i+1)-10)])
            self.paint.drawText(盘口X坐标位 + 3, 87 + (i * 18), buy_str)
            self.paint.drawText(盘口X坐标位 + r_fw + 20, 87 + (i * 18), 价格)
            self.paint.drawText(盘口X坐标位 + r_fw + 110, 87 + (i * 18), 手数)
            i += 1

    def 重绘(self):
        self.repaint()